/*
 Trabajo Practico 2 Ejercicio 2
 Entrega número: 1

 - Integrantes:
	- Martinez, Guillermo	DNI: 34510461
	- Meli, Marcos		DNI: 31832759
	- Reyes, Leandro	DNI: 34213699
	- Rodriguez, Lucas	DNI: 34265017
	- Cortez, Martin	DNI: 30440023
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>

// Funcion de errores
void error(char*);

// Controlador de señales
void controlador(int);

// Variable global de control
int control=0;

int main(int argc, char *argv[])
{
	char *args[] = {"-eo pcpu,pid",(char *) 0};
	char string[100];
	int pipeline[2],pidp=0,pidp_ant=0;
	float pcpu=0;
	pid_t ret;
	
	// Modifico comportamiento de senial
	signal(SIGCHLD,controlador);
	
	if(argc != 2 || *argv[1]<0 || *argv[1]>100)
		error("Error parámetros\n");
	
	// Genero pipe y conecto la pantalla a la entrada del pipe
	if(pipe(pipeline))
		error("No se pudo generar Pipe\n");
	
	if((ret=fork()) == -1)
		error("No se pudo crear proceso\n");

	// Si es padre
	if(ret)
	{
		// Conecto la salida del pipe con el teclado, cierro extremo no usado
		dup2(pipeline[0],0);
		close(pipeline[1]);
	
		// Duerme y descarta primer linea
		usleep(400);
		fgets(string,100,stdin);
		
		while(fscanf(stdin,"%f %d",&pcpu,&pidp) && pidp!=pidp_ant)
		{
			// Si el consumo es superior 
			if(pcpu > *argv[1])
			{
				printf("CPU: %f | PID: %d\nEnviando SIGTERM...\n",pcpu,pidp);
				kill(pidp,SIGTERM);
				sleep(5);
				if(!control)
				{
					printf("Proceso no respondio, enviando SIGKILL...\n");
					kill(pidp,SIGKILL);
				}
				
				else
					printf("Proceso terminado\n");
			}
			control=0;
			pidp_ant=pidp;
		}
	}
	
	else
	{
		// Conecto la entrada del pipe con la pantalla, cierro extremo no usado
		dup2(pipeline[1],1);
		close(pipeline[0]);
		
		// Ejecuto 'ps'
		if(execl("/bin/ps","/bin/ps","-eo","pcpu,pid",NULL) == -1)
			error("execl no se ejecuto");
	}
	
	return;
}

////////

void error(char* s)
{
	// Recibo cadena de error, muestro
	printf("Error: %s",s);
	exit(1);
}

void controlador(int signal)
{
	// Altero variable control
	control=1;
}